package scalahighlevel

/**
  * 5、协变、逆变
        （*）看成是视图界定的一个扩展
    Scala的协变: 一个泛型类接收的泛型参数的值可以是本身的类型或者是子类的类型
             在泛型前  +
    Scala的逆变： 一个泛型类接收的泛型参数的值可以是本身的类型或者是父类的类型
              语法： -号
  */
//动物
class Animal {}
//子类：鸟
class Bird extends Animal

//子类：麻雀
class Sparrow extends Bird

//类：吃东西（动作） 协变
//class EatSomething[+T](t:T){}

//定义吃东西的类(逆变)
class EatSomething[-T](t:T){}

object Animal {
  def main(args: Array[String]): Unit = {
    /**
      * 协变代码
      */
    //创建一个鸟吃东西的对象
    //    var c1:EatSomething[Bird] = new EatSomething[Bird](new Bird)

    //创建一个动物吃东西的对象
    //    var c2:EatSomething[Animal] = new EatSomething[Animal](new Animal)
    //问题：能否将c1付给c2？
    //原因：尽管Bird是Animal的子类，但是EatSomething[Bird]不是EatSomething[Animal]的子类
    //把EatSomething[Bird]  变成 EatSomething[Animal] 子类
    //    var c2:EatSomething[Animal] = c1
    //
    //    //再举个例子
    //    var c3:EatSomething[Sparrow] = new EatSomething[Sparrow](new Sparrow)
    //    var c4:EatSomething[Animal] = c3

    /**
      * 逆变代码
      */

    //创建一个鸟吃东西的对象
    var c1: EatSomething[Bird] = new EatSomething[Bird](new Bird)

    //创建一个麻雀吃东西的对象
    //var c2:EatSomething[Sparrow] = new EatSomething[Sparrow](new Sparrow)
    //问题：能否将c1 付给c2？
    //原因：尽管Bird是Sparrow的父类，但是EatSomething[Bird]不是EatSomething[Sparrow]的父类
    var c2: EatSomething[Sparrow] = c1
  }


}









